import ConvexGeometry from "./convex-geometry";
import CONSTANT from '../constant';

export default class SphereGeometry extends ConvexGeometry{
    constructor(radius) {
        super(CONSTANT.GEOMETRY_TYPE_SPHERE);
        this._radius = radius;
        this._gjkMargin = this._radius;
        this._updateMass();
    }

    //.....................................public......................................

    getRadius() {
        return this._radius;
    }

    //.....................................private......................................

    _updateMass() {
        let rsq=this._radius*this._radius;
        this._volume = 4.1887902047863861 * rsq * this._radius;
        let prs=0.4*rsq;
        let icf=this.inertiaCoeff;
        icf[0] = prs;
        icf[1] = 0;
        icf[2] = 0;
        icf[3] = 0;
        icf[4] = prs;
        icf[5] = 0;
        icf[6] = 0;
        icf[7] = 0;
        icf[8] = prs;
    }
    _computeAabb(_aabb,_tf) {
        let aabb=_aabb.elements,tf=_tf.elements;
        let r = this._radius;
        aabb[0] = tf[0] - r;aabb[1] = tf[1] - r;aabb[2] = tf[2] - r;
        aabb[3] = tf[0] + r;aabb[4] = tf[1] + r;aabb[5] = tf[2] + r;
    }
    computeLocalSupportingVertex(dir,out) {
        let es=out.elements;
        es[0]=es[1]=es[2]=0;
    }
    _rayCastLocal(beginX,beginY,beginZ,endX,endY,endZ,hit) {
        let dX = endX - beginX,dY = endY - beginY,dZ = endZ - beginZ;
        let a = dX * dX + dY * dY + dZ * dZ;
        let b = beginX * dX + beginY * dY + beginZ * dZ;
        let D = b * b - a * (beginX * beginX + beginY * beginY + beginZ * beginZ - this._radius * this._radius);
        if(D < 0) {
            return false;
        }
        let t = (-b - Math.sqrt(D)) / a;
        if(t < 0 || t > 1) {
            return false;
        }
        let hitPosX = beginX + dX * t,hitPosY = beginY + dY * t,hitPosZ = beginZ + dZ * t;
        let l = hitPosX * hitPosX + hitPosY * hitPosY + hitPosZ * hitPosZ;
        if(l > 0) {
            l = 1 / Math.sqrt(l);
        }
        let hitNormalX = hitPosX * l,hitNormalY = hitPosY * l,hitNormalZ = hitPosZ * l;
        let v = hit.position.elements;
        v[0] = hitPosX;v[1] = hitPosY;v[2] = hitPosZ;
        let v1 = hit.normal.elements;
        v1[0] = hitNormalX;v1[1] = hitNormalY;v1[2] = hitNormalZ;
        hit.fraction = t;
        return true;
    }
}